package org.jvending.provisioning.portal;

import org.jvending.provisioning.deliverable.BaseDeliverable;

import javax.provisioning.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;

public class AdapterControllerServlet extends HttpServlet {

    private static Logger logger = Logger.getLogger("AdapterControllerServlet");

    protected void service(HttpServletRequest request,
                           HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
        ProvisioningContext provisioningContext = (ProvisioningContext)
                this.getServletContext().getAttribute("javax.provisioning.ProvisioningContext");
        BundleDescriptor bundleDescriptor;
        final StringBuffer uriQueryBuffer = new StringBuffer();
        if (request.getServletPath().endsWith("maven2")) {
            final String fileName = request.getPathInfo();
            List<MatchPolicy> matchPolicies = new ArrayList<MatchPolicy>();
            MatchPolicy matchPolicy = new MatchPolicy() {
                public float doMatch(BundleDescriptor bundleDescriptor) {
                    DescriptorFile descriptorFile = (DescriptorFile) bundleDescriptor.getDescriptorFile();
                    if (descriptorFile == null || !descriptorFile.getMimeType().equals("text/x-maven-descriptor"))
                        return 0.0f;

                    for (Deliverable deliverable : descriptorFile.getContentFiles()) {
                        URI baseUri = ((BaseDeliverable) deliverable).getURI();
                        logger.info("JV: Base URI = /" + baseUri + ", File Name = " + fileName);
                        if (("/" + baseUri.toString()).equals(fileName)) {
                            uriQueryBuffer.append("&mimeType=").append(deliverable.getMimeType());
                            return 1.0f;
                        }
                    }
                    return 0.0f;
                }
            };
            matchPolicies.add(matchPolicy);
            Collection<BundleDescriptor> bundleDescriptors =
                    provisioningContext.getBundleRepository().getBundlesFor(null, matchPolicies);
            if (bundleDescriptors.size() == 0) {
                logger.info("Could not find content: URI = " + request.getRequestURI());
                return;
            }
            bundleDescriptor = (BundleDescriptor) bundleDescriptors.toArray()[0];
        } else {
            String bundleId = request.getParameter("bundleId");
            bundleDescriptor = provisioningContext.getBundleRepository().getBundleByID(bundleId);
        }

        DeliveryContext deliveryContext = provisioningContext.getDeliveryContext(request);

        /* This is where you can do authentication/authorization of the user
        * String userId = deliveryContext.getUser();
        * authenticationModule.authenticate(userId);
        * ....
        */
        FulfillmentTask fulfillmentTask;

        try {
            fulfillmentTask = provisioningContext.createFulfillmentTask(bundleDescriptor, deliveryContext);
            logger.info("Create task = " + fulfillmentTask.toString());
        } catch (ProvisioningException e) {
            e.printStackTrace();
            throw new IOException("JV: Could not create a FulfillmentTask: URI = " + request.getRequestURI());
        }

        /*IF WAP PUSH - use this fulfillmentTask.getDeliveryURI(); for the delivery URL
         * This may be consider WAP Push if user-agent is incapable of supporting the content.
         * Use the network id (MSISDN) for the recipient
         */

        try {
            URI uri = new URI(fulfillmentTask.getDeliveryURI());
            logger.info("Sending to URI = " + uri.toString() + uriQueryBuffer.toString());
            if (uri.isAbsolute()) response.sendRedirect(uri.toString() + uriQueryBuffer.toString());
            else request.getRequestDispatcher(uri.toString()).forward(request, response);
        } catch (ProvisioningException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
}
